package com.baijiaoxi.common.utils.jdk;

import com.baijiaoxi.common.model.base.CoreException;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

import static com.baijiaoxi.common.model.base.CommonError.fileNotExist;

@Slf4j
public class ReloadClassLoader extends URLClassLoader {
    private URL[] urls;//扫描的jar包路径

    public ReloadClassLoader(URL[] urls) {
        //1. 指定搜索路径和父加载器：AppClassLoader
        super(urls, ReloadClassLoader.class.getClassLoader());
        this.urls = urls;
    }

    /**
     * 重载loadClass方法
     *
     * @param name
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        if (urls != null && urls.length > 0) {
            Class<?> c = null;
            try {
                //2. 先在自己的扫描路径中找class
                c = findClass(name);//该方法存在于URLClassLoader中，如果加载不到指定类，会报ClassNotFoundException
            } catch (ClassNotFoundException e) {
                //3. 找不到就让 parent 去加载
                c = this.getParent().loadClass(name);
            }
            return c;
        }
        return super.loadClass(name);
    }

    /**
     * @param jarFilePaths Jar包地址
     * @param className    全类名
     * @return
     */
    public Class<?> loadClassFormJAR(List<String> jarFilePaths, String className) {
        List<URL> urls = new ArrayList<>();
        jarFilePaths.stream().forEach(jarFilePath -> {
            try {
                urls.add(new File(jarFilePath).toURI().toURL());
            } catch (MalformedURLException e) {
                throw CoreException.create(fileNotExist, e, jarFilePath);
            }
        });
        if (urls.isEmpty())
            throw CoreException.create(fileNotExist, "没有找到任何匹配文件");
        ReloadClassLoader reloadClassLoader = new ReloadClassLoader(urls.toArray(URL[]::new));
        try {
            Class<?> aClass = reloadClassLoader.loadClass(className);
            return aClass;
        } catch (ClassNotFoundException classNotFoundException) {
            throw CoreException.create(fileNotExist, classNotFoundException);
        }
    }

    /**
     * @param jarFilePath
     * @param className
     * @return
     */
    public Class<?> loadClassFormJAR(String jarFilePath, String className) {
        return loadClassFormJAR(List.of(jarFilePath), className);
    }

}
